package proyectoCisco;

import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import javax.servlet.*;
import org.apache.log4j.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Clase para conexión y gestión del router
 * @author José Manuel Śanchez Bernabéu
 */
public class rsh implements Serializable {

    private String Host;
    private String Username;
    private String Command;
    private String Contrasenya;
    public static Properties config = null;
    Logger log = Logger.getLogger(rsh.class);

    /**
     * Constructor de la clase
     */
    public rsh()
    {
        try
        {
            config=Configurator.load();
            setUsername(config.getProperty("userRouter"));
            setContrasenya(config.getProperty("passwordRouter"));
        }
        catch(Exception ex)
        {
            log.error("Error al cargar el fichero de configuracion : proyecto.properties " + ex.getMessage());
        }
    }

    /**
     * Constructor sobrecargado de la clase
     * @param new_host host a conectarse
     * @param new_command comando a enviar
     */
    public rsh(String new_host, String new_command)
    {
        try
        {
            config = Configurator.load();
            setHost(new_host);
            setUsername(config.getProperty("userRouter"));
            setContrasenya(config.getProperty("passwordRouter"));
            setCommand(new_command);
        }
        catch(Exception ex)
        {
            log.error("Error al cargar el fichero de configuracion : proyecto.properties " + ex.getMessage());
        }
    }

    /**
     * Metodo get para el campo Host
     * @return Host
     */
    public String getHost() {
        return Host;
    }

    /**
     * Metodo set para el campo Host
     * @param Host
     */
    public void setHost(String Host) {
        this.Host = Host;
    }

    /**
     * Metodo get para el campo Username
     * @return Username
     */
    public String getUsername() {
        return Username;
    }

    /**
     * Metodo set para el campo Username
     * @param Username
     */
    public void setUsername(String Username) {
        this.Username = Username;
    }

    /**
     * Metodo get para el campo Contrasenya
     * @return Contrasenya
     */
    public String getContrasenya() {
        return Contrasenya;
    }

    /**
     * Metodo set para el campo Contrsenya
     * @param Contrasenya
     */
    public void setContrasenya(String Contrasenya) {
        this.Contrasenya = Contrasenya;
    }

    /**
     * Metodo get para el campo Command
     * @return Command
     */
    public String getCommand() {
        return Command;
    }

    /**
     * Metodo set para el campo Command
     * @param Command
     */
    public void setCommand(String Command) {
        this.Command = Command;
    }

    /**
     * Metodo para la ejecucion de comandos remotos
     * @return
     */
    public String Run()
    {
        int puertoOrigen, puertoDestino,intento=0;
        Boolean conexion=true;
        String retorno="",respuesta="",ceroString,comando="",direccionLocalhost="";
        Socket echoSocket = null;
        byte[] cero= {0x00};
        InetAddress direccionLocal;

        ceroString = new String(cero);

        if(!config.getProperty("ipLocal").equals(""))
        {
            direccionLocalhost=config.getProperty("ipLocal");
            log.info("Preparando la peticion desde el host con IP local: "+direccionLocalhost);
            // Definimos la cadena con el usuario, contrasenya y el comando
            comando=ceroString+this.Username+ceroString+this.Contrasenya+ceroString+this.Command+ceroString;
            log.debug("Preparando el comando a enviar al router. Comando: "+comando);
            
            puertoOrigen=Integer.parseInt(config.getProperty("puertoOrigen"));
            puertoDestino=Integer.parseInt(config.getProperty("puertoDestino"));

            // Abrimos sockets mientras estén ocupados los puertos,
            // empezando por el puerto origen especificado
            // en el fichero de configuración
            do{
                try
                {
                    // Obtenemos la direccion local del equipo
                    direccionLocal = InetAddress.getByName(direccionLocalhost);

                    // Abrimos el socket
                    log.debug("Abriendo socket desde la direccion "+direccionLocalhost +":"+puertoOrigen +" al router con IP: "+this.Host+":"+puertoDestino);
                    
                    echoSocket = new Socket(this.Host, puertoDestino, direccionLocal, puertoOrigen++);
                    log.debug("Conectado al host remoto "+ echoSocket.getInetAddress() +
                              " al puerto "+ echoSocket.getPort() +
                              " desde el puerto "+ echoSocket.getLocalPort() +
                              " desde la direccion local " + echoSocket.getLocalAddress());

                    DataInputStream remoteInput = new DataInputStream(echoSocket.getInputStream());
                    DataOutputStream remoteOutput= new DataOutputStream(echoSocket.getOutputStream());

                    remoteOutput.writeBytes(comando);
                    log.info("Mandando comando al router");
                    log.debug("Mandando comando al router. Comando: "+comando);

                    if (this.Command.equals("sh startup-config"))
                    {
                        respuesta=remoteInput.readLine(); // leemos una linea porque devuelve un caracter extraño
                    }
                    if (this.Command.equals("sh running-config"))
                    {
                        respuesta=remoteInput.readLine(); // leemos una linea porque devuelve un caracter extraño
                        respuesta=remoteInput.readLine();
                        respuesta=remoteInput.readLine();
                    }

                    // Si es otro comando
                    respuesta=remoteInput.readLine();
                    
                    do{
                        respuesta=remoteInput.readLine();
                        if(respuesta!=null)
                            retorno+=respuesta+"\n";
                    }while(respuesta!=null);


                    log.debug("Respuesta del router. Respuesta: "+retorno);

                    remoteOutput.close();
                    remoteInput.close();

                    conexion=true;
                }
                catch (UnknownHostException e)
                {
                    log.error("Error(UnknownHostException) al mandar comando al router. Error: "+e.getMessage());
                    conexion=true; // Conexion true para salir del bucle
                }
                catch (IOException e)
                {
                    log.error("Error(IOException) al mandar comando al router. Error: "+e.getMessage());
                    log.error("Intento de conexion ("+intento+"): "+e.getMessage());
                    conexion=false;
                    // Si al intentar abrir 50 veces la conexion con el puerto está ocupada para
                    intento++;
                }
                catch (Exception e)
                {
                    log.error("Error(Exception) al mandar comando al router. Error: "+e.getMessage());
                    conexion=false;
                }
                finally {
                    try{
                        log.debug("Cerramos socket");
                        if(echoSocket != null)
                            echoSocket.close();
                    }
                    catch (IOException e)
                    {
                        log.error("Error(IOException) al cerrar el socket. Error: "+e.getMessage());
                    }
                }
            }while(conexion==false && puertoOrigen<65535 && intento<50);
        }
        else
            log.error("Error. No se ha definido una direccion ip local en el fichero de propiedades 'proyectoCisco.properties'");

        if(intento==50)
            retorno="Error al intentar conectar al router";

        return retorno;
    }

    /**
     * Metodo para cargar un fichero de configuracion o IOS al router
     */
    public void CargarFichero()
    {
        int puertoOrigen, puertoDestino,intento=0;
        Boolean conexion=true;
        String respuesta,ceroString,comando="",direccionLocalhost="";
        Socket echoSocket = null;
        byte[] cero= {0x00};
        ceroString = new String(cero);
        InetAddress direccionLocal;

        if(!config.getProperty("ipLocal").equals(""))
        {
            direccionLocalhost=config.getProperty("ipLocal");
            log.info("Preparando la peticion desde el host con IP local: "+direccionLocalhost);
            comando=ceroString+this.Username+ceroString+this.Contrasenya+ceroString+this.Command+ceroString;
            log.debug("Preparando el comando a enviar al router. Comando: "+comando);
            puertoOrigen=Integer.parseInt(config.getProperty("puertoOrigen"));
            puertoDestino=Integer.parseInt(config.getProperty("puertoDestino"));

            // Abrimos sockets mientras estén ocupados los puertos,
            // empezando por el puerto origen especificado
            // en el fichero de configuración
            do{

                try
                {
                    // Obtenemos la direccion local del equipo
                    direccionLocal = InetAddress.getByName(direccionLocalhost);

                   // Abrimos el socket
                    log.debug("Abriendo socket desde la direccion "+direccionLocalhost +":"+puertoOrigen +" al router con IP: "+this.Host+":"+puertoDestino);
                    echoSocket = new Socket(this.Host, puertoDestino, direccionLocal, puertoOrigen++);

                    DataInputStream remoteInput = new DataInputStream(echoSocket.getInputStream());
                    DataOutputStream remoteOutput= new DataOutputStream(echoSocket.getOutputStream());

                    remoteOutput.writeBytes(comando);
                    log.info("Mandando comando al router");
                    log.debug("Mandando comando al router. Comando: "+comando);

                    // si es copy running-config
                    respuesta=remoteInput.readLine();
                    log.debug("Respuesta del router. Respuesta: "+respuesta);
                    comando="";
                    comando=ceroString+"\n"+ceroString;
                    
                    remoteOutput.writeBytes(comando);
                    
                    ///// Esperamos a que cargue
                    String otro="";

                    do{
                        otro=remoteInput.readLine();
                    }while(otro!=null);

                    
                    remoteOutput.close();
                    remoteInput.close();
                    conexion=true;
                }
                catch (UnknownHostException e)
                {
                   log.error("Error(UnknownHostException) al cargar fichero al router. Error: "+e.getMessage());
                   conexion=true; // Conexion true para salir del bucle
                }
                catch (IOException e)
                {
                    log.error("Error(IOException) al cargar fichero al router. Error: "+e.getMessage());
                    log.error("Intento de conexion ("+intento+"): "+e.getMessage());
                    conexion=false;
                    // Si al intentar abrir 50 veces la conexion con el puerto está ocupada para
                    intento++;
                }
                catch (Exception e)
                {
                    log.error("Error(Exception) al cargar fichero al router. Error: "+e.getMessage());
                    conexion=false;
                }
                finally {
                    try{
                        log.debug("Cerrando socket");
                        if(echoSocket != null)
                            echoSocket.close();
                    }
                    catch (IOException e)
                    {
                        log.error("Error(IOException) al cerrar el socket. Error: "+e.getMessage());
                    }
                }
            }while(conexion==false && puertoOrigen<65535 && intento<50);
        }
        else
            log.error("Error. No se ha definido una direccion ip local en el fichero de propiedades 'proyectoCisco.properties'");
    }


    public void reload()
    {
        int puertoOrigen, puertoDestino,intento=0;
        Boolean conexion=true;
        String respuesta,ceroString,comando="",direccionLocalhost="";
        Socket echoSocket = null;
        byte[] cero= {0x00};
        ceroString = new String(cero);
        InetAddress direccionLocal;

        if(!config.getProperty("ipLocal").equals(""))
        {
            direccionLocalhost=config.getProperty("ipLocal");
            log.info("Preparando la peticion desde el host con IP local: "+direccionLocalhost);
            log.debug("Preparando el comando a enviar al router. Comando: "+comando);
            puertoOrigen=Integer.parseInt(config.getProperty("puertoOrigen"));
            puertoDestino=Integer.parseInt(config.getProperty("puertoDestino"));

            // Abrimos sockets mientras estén ocupados los puertos,
            // empezando por el puerto origen especificado
            // en el fichero de configuración
            do{

                try
                {
                    // Obtenemos la direccion local del equipo
                    direccionLocal = InetAddress.getByName(direccionLocalhost);

                    // Abrimos el socket
                    log.debug("Abriendo socket desde la direccion "+direccionLocalhost +":"+puertoOrigen +" al router con IP: "+this.Host+":"+puertoDestino);
                    echoSocket = new Socket(this.Host, puertoDestino, direccionLocal, puertoOrigen++);

                    DataInputStream remoteInput = new DataInputStream(echoSocket.getInputStream());
                    DataOutputStream remoteOutput= new DataOutputStream(echoSocket.getOutputStream());
                    // comando = \0usuario\0password\0reload\0yes\0\0yes\0R\0
                    comando=ceroString+this.Username+ceroString+this.Contrasenya+ceroString+"reload"+ceroString+"yes"+ceroString+ceroString+"yes"+ceroString+"R"+ceroString;
                    // Ahora mandamos reload
                    remoteOutput.writeBytes(comando);
                    respuesta=remoteInput.readLine();
                    comando="";
                    comando="yes";
                    remoteOutput.writeBytes(comando);
                    // Leemos lo que nos pueda devolver
                    String otro="";

                    do{
                        otro=remoteInput.readLine();
                    }while(otro!=null);
                    
                    remoteOutput.close();
                    remoteInput.close();
                    conexion=true;
                }
                catch (UnknownHostException e)
                {
                   log.error("Error(UnknownHostException) al hacer reload. Error: "+e.getMessage());
                   conexion=true; // Conexion true para salir del bucle
                }
                catch (IOException e)
                {
                    log.error("Error(IOException) al hacer reload. Error: "+e.getMessage());
                    log.error("Intento de conexion ("+intento+"): "+e.getMessage());
                    conexion=false;
                    // Si al intentar abrir 50 veces la conexion con el puerto está ocupada para
                    intento++;
                }
                catch (Exception e)
                {
                    log.error("Error(Exception) al hacer reload. Error: "+e.getMessage());
                    conexion=false;
                }
                finally {
                    try{
                        log.debug("Cerrando socket");
                        if(echoSocket != null)
                            echoSocket.close();
                    }
                    catch (IOException e)
                    {
                        log.error("Error(IOException) al cerrar el socket. Error: "+e.getMessage());
                    }
                }
            }while(conexion==false && puertoOrigen<65535 && intento<50);
        }
        else
            log.error("Error. No se ha definido una direccion ip local en el fichero de propiedades 'proyectoCisco.properties'");
    }


    /**
     * Metodo que almacena la configuracion de un router en un fichero
     * @param ip IP del router a obtener la configuracion
     * @param comando Comando para obtener la configuracion
     * @param directorio Directorio donde se almacena la configuracion del router
     * @return
     */
    public String saveOnFile(String ip, String comando,String directorio)
    {
        String retorno="",nombreFichero="",nombreDirectorio="",nombreRouter="",cadenaFecha="",texto="";
        SimpleDateFormat formato = new SimpleDateFormat("dd-MMM-yyyy-HH:mm:ss");
        File ficheroConfiguracion;
        Date fechaActual = new Date();
        claseBBDD baseDatos = new claseBBDD();
        //directorio=config.getProperty("directorioTemporal");
        directorio+="configuraciones/";
        cadenaFecha=formato.format(fechaActual);
        
        // Datos router
        setHost(ip);
        setCommand(comando);

        // Obtenemos la configuracion del router
        texto = Run();
        nombreRouter = baseDatos.obtenerNombreRouter(ip);

        if(!texto.equals(""))
        {
            try
            {
                nombreDirectorio=directorio+nombreRouter+"-"+ip+"_"+cadenaFecha+".conf";
                nombreFichero=nombreRouter+"-"+ip+"_"+cadenaFecha+".conf";
                ficheroConfiguracion = new File(nombreDirectorio);

                log.info("Creando fichero '"+nombreFichero+"' para almacenar la configuracion del router "+nombreRouter);

                if(ficheroConfiguracion.createNewFile())
                {
                    BufferedWriter bw = new BufferedWriter(new FileWriter(ficheroConfiguracion));
                    bw.write(texto);
                    bw.close();
                    retorno = nombreFichero;

                    log.info("Fichero creado con la configuracion del router");
                    log.debug("Fichero creado con la configuracion del router. Ruta: "+nombreDirectorio);
                }
                else
                {
                    retorno = "error";
                    log.error("Error al crear el fichero de configuracion");
                }
            }
            catch(IOException e)
            {
                retorno = "error";
                log.error("Error al guardar la configuracion del router en un fichero. Error: "+e.getMessage());
            }
            catch(Exception e)
            {
                retorno = "error";
                log.error("Error al guardar la configuracion del router en un fichero. Error: "+e.getMessage());
            }
        }
        else
        {
            retorno = "error";
            log.error("Error al guardar la configuracion del router en un fichero. Error: La configuracion devuelva por el router es cadena vacia");
        }

        return retorno;
    }

    /**
     * Metodo que almacena la modificacion de la configuracion de un router en un fichero
     * @param ip IP del router a obtener la configuracion
     * @param configuracion Configuracion modificada
     * @return
     */
    public String saveModificacionOnFile(String ip, String configuracion)
    {
        String retorno="",nombreFichero="",nombreDirectorio="",texto="";
        File ficheroConfiguracion;

        // Datos router
        setHost(ip);

        // Obtenemos la configuracion del router
        texto = configuracion;

        if(!texto.equals(""))
        {
            try
            {
                nombreDirectorio=config.getProperty("directorioTFTP")+"startup-config";
                ficheroConfiguracion = new File(nombreDirectorio);

                log.info("Creando fichero startup-config para almacenar la configuracion del router ");

                if(ficheroConfiguracion.createNewFile())
                {
                    BufferedWriter bw = new BufferedWriter(new FileWriter(ficheroConfiguracion));
                    bw.write(texto);
                    bw.close();
                    retorno = "startup-config";

                    log.info("Fichero creado con la configuracion del router");
                    log.debug("Fichero creado con la configuracion del router. Ruta: "+nombreDirectorio);
                }
                else
                {
                    retorno = "error";
                    log.error("Error al crear el fichero de configuracion");
                }
            }
            catch(IOException e)
            {
                retorno = "error";
                log.error("Error al guardar la configuracion del router en un fichero. Error: "+e.getMessage());
            }
            catch(Exception e)
            {
                retorno = "error";
                log.error("Error al guardar la configuracion del router en un fichero. Error: "+e.getMessage());
            }
        }
        else
        {
            retorno = "error";
            log.error("Error al guardar la configuracion del router en un fichero. Error: La configuracion devuelva por el router es cadena vacia");
        }

        return retorno;
    }

    /**
     * Metod que borra de la carpeta tftp los ficheros que se han subido al router
     * @param path
     */
    public static void borraCarpeta(String path){
        File f1 = new File(path);
        File[] files = f1.listFiles();
        for(int i=0;i<files.length;i++)
        {
            if(files[i].isDirectory())
            {
                try
                {
                    borraCarpeta(files[i].getCanonicalPath());
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                files[i].delete();
            }
            else
            {
                files[i].delete();
            }
        }
        //f1.delete();
     }
     public int ContarFicheros(String path)
     {
         File file = new File(path);

         if (!file.isDirectory())
         {
           return 1;
         }

         int count = 0;
         File[] files = file.listFiles();
         if (files != null)
         {
            for (File f: files)
            {
              count++;
            }
         }
            return count;
        }

     public long TamanyoCarpetaFicheros(String path)
     {
         File file = new File(path);

         if (!file.isDirectory())
         {
           return 1;
         }

         long count = 0;
         File[] files = file.listFiles();
         if (files != null)
         {
            for (File f: files)
            {
              count+=f.length();
            }
         }
            return count;
        }
     

    public static ArrayList ObtenerListadoImagenes(String texto)
    {
        ArrayList<String> listado = new ArrayList<String>();
        ArrayList<String> listadoRetorno = new ArrayList<String>();
        Matcher mat=null;
        Pattern pat=Pattern.compile("(bin)$");

        String aux="";
        int i=0;
        
        do{
            aux="";
            if(texto.charAt(i)!='\n')
            {
                do{
                    aux+=texto.charAt(i);
                    i++;
                }while(texto.charAt(i)!='\n');

                listado.add(aux);
            }
            i++;
        }while(i<texto.length());

        // Ya lo tengo separado por lineas
        // Ahora quito la primera linea y la ultima

        listado.remove(0);
        listado.remove(listado.size()-1);

        for(int j=0;j<listado.size();j++)
        {
            ArrayList<String> tokens = new ArrayList<String>();
            Scanner tokenize = new Scanner(listado.get(j));
            while (tokenize.hasNext()) {
                tokens.add(tokenize.next());
            }

            for(int k=0;k<tokens.size();k++)
            {
                    mat=pat.matcher(tokens.get(k));
                    if(mat.find())
                    {
                        System.out.println("Encontrado: "+tokens.get(k));
                        listadoRetorno.add(tokens.get(k));
                    }
            }
        }        

        return listadoRetorno;
    }

    /**
     * Metodo que almacena la configuracion de un router en un fichero
     * @param ip IP del router a obtener la configuracion
     * @param comando Comando para obtener la configuracion
     * @param directorio Directorio donde se almacena la configuracion del router
     * @return
     */
    public String saveIOSOnFile(String ip, String nombre, String dir)
    {
        int puertoOrigen, puertoDestino,intento=0;
        Boolean conexion=true;
        String respuesta,ceroString,comando="",direccionLocalhost="", retorno="";
        Socket echoSocket = null;
        byte[] cero= {0x00};
        ceroString = new String(cero);
        InetAddress direccionLocal;
        this.setHost(ip);

        if(!config.getProperty("ipLocal").equals(""))
        {
            direccionLocalhost=config.getProperty("ipLocal");
            log.info("Preparando la peticion desde el host con IP local: "+direccionLocalhost);
            comando=ceroString+this.Username+ceroString+this.Contrasenya+ceroString
                    +"copy flash:"+nombre + " tftp://" + direccionLocalhost + "/" + nombre + ceroString;

            log.debug("Preparando el comando a enviar al router. Comando: "+comando);
            puertoOrigen=Integer.parseInt(config.getProperty("puertoOrigen"));
            puertoDestino=Integer.parseInt(config.getProperty("puertoDestino"));

            // Abrimos sockets mientras estén ocupados los puertos,
            // empezando por el puerto origen especificado
            // en el fichero de configuración
            do{
                // copy flash:nombre tftp://192.168.1.34/nombre.bin
                try
                {
                    // Obtenemos la direccion local del equipo
                    direccionLocal = InetAddress.getByName(direccionLocalhost);

                   // Abrimos el socket
                    log.debug("Abriendo socket desde la direccion "+direccionLocalhost +":"+puertoOrigen +" al router con IP: "+this.Host+":"+puertoDestino);
                    echoSocket = new Socket(this.Host, puertoDestino, direccionLocal, puertoOrigen++);

                    DataInputStream remoteInput = new DataInputStream(echoSocket.getInputStream());
                    DataOutputStream remoteOutput= new DataOutputStream(echoSocket.getOutputStream());

                    remoteOutput.writeBytes(comando);
                    log.info("Mandando comando al router");
                    log.debug("Mandando comando al router. Comando: "+comando);

                    respuesta=remoteInput.readLine();
                    log.debug("Respuesta del router. Respuesta: "+respuesta);
                    comando="";
                    comando=ceroString+"\n"+ceroString;

                    remoteOutput.writeBytes(comando);

                    respuesta=remoteInput.readLine();
                    log.debug("Respuesta del router. Respuesta: "+respuesta);
                    comando="";
                    comando=ceroString+"\n"+ceroString;

                    remoteOutput.writeBytes(comando);

                    ///// Esperamos a que cargue
                    String otro="";

                    do{
                        otro=remoteInput.readLine();
                    }while(otro!=null);

                    //Thread.currentThread().sleep(3000);//sleep for 1000 ms

                    remoteOutput.close();
                    remoteInput.close();
                    conexion=true;

                    // Ahora copiamos el fichero en el directorio configuraciones
                    File file = new File(config.getProperty("directorioTFTP")+nombre);
                    String destino=dir+"configuraciones/"+nombre;
                    file.renameTo(new File(destino));

                    retorno="/configuraciones/"+nombre;
                }
                catch (UnknownHostException e)
                {
                   log.error("Error(UnknownHostException) al cargar fichero al router. Error: "+e.getMessage());
                   conexion=true; // Conexion true para salir del bucle
                }
                catch (IOException e)
                {
                    log.error("Error(IOException) al cargar fichero al router. Error: "+e.getMessage());
                    log.error("Intento de conexion ("+intento+"): "+e.getMessage());
                    conexion=false;
                    // Si al intentar abrir 50 veces la conexion con el puerto está ocupada para
                    intento++;
                }
                catch (Exception e)
                {
                    log.error("Error(Exception) al cargar fichero al router. Error: "+e.getMessage());
                    conexion=false;
                }
                finally {
                    try{
                        log.debug("Cerrando socket");
                        if(echoSocket != null)
                            echoSocket.close();
                    }
                    catch (IOException e)
                    {
                        log.error("Error(IOException) al cerrar el socket. Error: "+e.getMessage());
                    }
                }
            }while(conexion==false && puertoOrigen<65535 && intento<50);
        }
        else
            log.error("Error. No se ha definido una direccion ip local en el fichero de propiedades 'proyectoCisco.properties'");

        if(intento==50)
            retorno="Error";

        return retorno;
    }

    public void CopiarRunStartup()
    {
        int puertoOrigen, puertoDestino,intento=0;
        Boolean conexion=true;
        String respuesta="",ceroString,comando="",direccionLocalhost="";
        Socket echoSocket = null;
        byte[] cero= {0x00};
        InetAddress direccionLocal;

        ceroString = new String(cero);

        if(!config.getProperty("ipLocal").equals(""))
        {
            direccionLocalhost=config.getProperty("ipLocal");
            log.info("Preparando la peticion desde el host con IP local: "+direccionLocalhost);
            // Definimos la cadena con el usuario, contrasenya y el comando
            comando=ceroString+this.Username+ceroString+this.Contrasenya+ceroString+this.Command+ceroString;
            log.debug("Preparando el comando a enviar al router. Comando: "+comando);

            puertoOrigen=Integer.parseInt(config.getProperty("puertoOrigen"));
            puertoDestino=Integer.parseInt(config.getProperty("puertoDestino"));

            // Abrimos sockets mientras estén ocupados los puertos,
            // empezando por el puerto origen especificado
            // en el fichero de configuración
            do{
                try
                {
                    // Obtenemos la direccion local del equipo
                    direccionLocal = InetAddress.getByName(direccionLocalhost);

                    // Abrimos el socket
                    log.debug("Abriendo socket desde la direccion "+direccionLocalhost +":"+puertoOrigen +" al router con IP: "+this.Host+":"+puertoDestino);

                    echoSocket = new Socket(this.Host, puertoDestino, direccionLocal, puertoOrigen++);
                    log.debug("Conectado al host remoto "+ echoSocket.getInetAddress() +
                              " al puerto "+ echoSocket.getPort() +
                              " desde el puerto "+ echoSocket.getLocalPort() +
                              " desde la direccion local " + echoSocket.getLocalAddress());

                    DataInputStream remoteInput = new DataInputStream(echoSocket.getInputStream());
                    DataOutputStream remoteOutput= new DataOutputStream(echoSocket.getOutputStream());

                    remoteOutput.writeBytes(comando);
                    log.info("Mandando comando al router");
                    log.debug("Mandando comando al router. Comando: "+comando);

                    respuesta=remoteInput.readLine();

                    comando="";
                    comando=ceroString+"\n"+ceroString;

                    remoteOutput.writeBytes(comando);

                    // Leemos lo que nos pueda devolver
                    String otro="";

                    do{
                        otro=remoteInput.readLine();
                    }while(otro!=null);

                    remoteOutput.close();
                    remoteInput.close();

                    conexion=true;
                }
                catch (UnknownHostException e)
                {
                    log.error("Error(UnknownHostException) al mandar comando al router. Error: "+e.getMessage());
                    conexion=true; // Conexion true para salir del bucle
                }
                catch (IOException e)
                {
                    log.error("Error(IOException) al mandar comando al router. Error: "+e.getMessage());
                    log.error("Intento de conexion ("+intento+"): "+e.getMessage());
                    conexion=false;
                    // Si al intentar abrir 50 veces la conexion con el puerto está ocupada para
                    intento++;
                }
                catch (Exception e)
                {
                    log.error("Error(Exception) al mandar comando al router. Error: "+e.getMessage());
                    conexion=false;
                }
                finally {
                    try{
                        log.debug("Cerramos socket");
                        if(echoSocket != null)
                            echoSocket.close();
                    }
                    catch (IOException e)
                    {
                        log.error("Error(IOException) al cerrar el socket. Error: "+e.getMessage());
                    }
                }
            }while(conexion==false && puertoOrigen<65535 && intento<50);
        }
        else
            log.error("Error. No se ha definido una direccion ip local en el fichero de propiedades 'proyectoCisco.properties'");
    }
}
